#ifndef ELEMENTLIST_H
#define ELEMENTLIST_H

#include <QDomElement>
#include <QDomDocument>


class SharedDomObject
{
    template <typename T>
    friend class ElementList;
public:
    SharedDomObject(QDomElement source);
    bool isNull();
    SharedDomObject clone();
    static QString tagName(); // override by subclass

protected:
    QDomElement m_source;

};


template <typename T>
class ElementList : public SharedDomObject
{
public:
    ElementList(QDomElement source) : SharedDomObject(source)
    {
    }

    static QString tagName()
    {
        return T::tagName().append("s");
    }

    int count()
    {
        int res = 0;
        QDomElement element = m_source.firstChildElement();
        while (!element.isNull()) {
            res++;
            element = element.nextSiblingElement();
        }
        return res;
    }

    inline int size()
    {
        return count();
    }

    void insertBefore(int index, const T &item)
    {
        m_source.insertBefore(item.m_source, findChildByIndex(index));
    }

    void append(const T &item)
    {
        m_source.appendChild(item.m_source);
    }

    bool moveTagOrder(int id, int toIndex)
    {
        return true;
    }

    void removeAt(int index)
    {
        m_source.removeChild(findChildByIndex(index));
    }

    bool isEmpty()
    {
        return (count() == 0);
    }

    T idRefer(int id)
    {
        return T(findChildById(id));
    }

    T operator[](int index)
    {
        return T(findChildByIndex(index));
    }

    T createNewChild(bool appendToList = true)
    {
        QDomElement child = m_source.ownerDocument().createElement(T::tagName());
        if (appendToList) {
            m_source.appendChild(child);
        }
        return T(child);
    }

    ElementList<T> clone()
    {
        return ElementList<T>(m_source.cloneNode().toElement());
    }

protected:
    QDomElement findChildByIndex(int index)
    {
        QDomElement child = m_source.firstChildElement();
        int i = 0;
        while (i < index && !child.isNull()) {
            child = child.nextSiblingElement();
            i++;
        }
        return child;
    }

    QDomElement findChildById(int id)
    {
        QDomElement child = m_source.firstChildElement();
        while (!child.isNull()) {
            if (child.attribute("id").toInt() == id)
                break;
            else
                child = child.nextSiblingElement();
        }
        return child;
    }

};

#endif // ELEMENTLIST_H
